﻿#include "ssMySQLConnection.h"
#include <sstream>


namespace StarSeeker
{

ssMySQLConnection::ssMySQLConnection()
{
	m_pConnect = 0;
	m_character = "set names utf8";
	m_port = 3306;
	m_affectedRows = 0;
	m_insertID = 0;
	m_result.Set(1024, true);
	m_resultSet.Init(1024 * 4);
	m_errno = 0;
	m_free = true;
}

ssMySQLConnection::~ssMySQLConnection()
{
	Exit();
}

bool ssMySQLConnection::Init(const char *pIP, u32 port, const char *pAccount, const char *pPW, const char *pDBName)
{
	m_IP = pIP;
	m_port = port;
	m_account = pAccount;
	m_password = pPW;
	m_name = pDBName;
	return Connect();
}

void ssMySQLConnection::Exit()
{
	ClearResult();
	if (m_pConnect)
	{
		mysql_close(m_pConnect);
		m_pConnect = 0;
	}
}

void ssMySQLConnection::SetCharacter(const char *pc)
{
	m_character = "set names ";
	m_character += pc;
	if (m_pConnect)
	{
		mysql_query(m_pConnect, pc);
	}
}

void ssMySQLConnection::SelectDB(const char *pDBName)
{
	m_name = pDBName;
	if (m_pConnect)
	{
		if (mysql_select_db(m_pConnect, pDBName))
		{
			CheckError("mysql_select_db");
		}
	}
}

bool ssMySQLConnection::Execute(const char * sql)
{
	if (Connect())
	{
		if (mysql_query(m_pConnect, sql))
		{
			CheckError(sql);
			return false;
		}
		return true;
	}
	return false;
}

//bool ssMySQLConnection::Query(const char *sql)
//{
//	if (Connect())
//	{
//		ClearResult();
//		if (mysql_query(m_pConnect, sql))
//		{
//			CheckError(sql);
//			return false;
//		}
//		MYSQL_RES * res = mysql_store_result(m_pConnect);
//		if (res)
//		{
//			m_fieldCount = mysql_num_fields(res);
//			m_rowCount = mysql_num_rows(res);
//
//			mysql_data_seek(res, 0);
//			m_currentRow = mysql_fetch_row(m_result);
//		}
//		return true;
//	}
//	return false;
//}

bool ssMySQLConnection::Transaction()
{
	return Execute("BEGIN;");
}

bool ssMySQLConnection::Commit()
{
	return Execute("COMMIT;");
}

bool ssMySQLConnection::Rollback()
{
	return Execute("ROLLBACK;");
}

void ssMySQLConnection::RePrepare()
{
}

bool ssMySQLConnection::Connect()
{
	if (m_pConnect)
	{
		int ret = mysql_ping(m_pConnect);
		if (ret)
		{
			Exit();
		}
	}
	if (!m_pConnect)
	{
		//初始化
		m_pConnect = mysql_init(NULL);
		if (!m_pConnect)
		{
			CheckError("mysql_init");
			return false;
		}
		//my_bool mybool = 1;
		//mysql_options(m_pConnect, MYSQL_OPT_RECONNECT, &mybool);
		//连接
		if (!mysql_real_connect(m_pConnect, m_IP.c_str(), m_account.c_str(), m_password.c_str(), m_name.c_str(), m_port, NULL, CLIENT_MULTI_STATEMENTS | CLIENT_INTERACTIVE))
		{
			CheckError("mysql_real_connect");
			mysql_close(m_pConnect);
			m_pConnect = 0;
			return false;
		}
		mysql_query(m_pConnect, m_character.c_str());
		m_serverVersion = mysql_get_server_info(m_pConnect);
		m_clientVersion = mysql_get_client_info();
		mysql_query(m_pConnect, "set wait_timeout = 432200");
		RePrepare();
		return true;
	}
	return true;
}

void ssMySQLConnection::CleanBuffer()
{
	m_result.Clear();
	m_resultSet.Clear();
	m_result.Set(1024, true);
	m_resultSet.Init(1024 * 4);
}

void ssMySQLConnection::ClearResult()
{
	if (m_pConnect)
	{
		while (0 == mysql_next_result(m_pConnect))
		{
			MYSQL_RES* res = mysql_store_result(m_pConnect);
			mysql_free_result(res);
		}
	}
}

void ssMySQLConnection::CheckError(const char * str)
{
	m_errno = mysql_errno(m_pConnect);
	std::ostringstream s;
	s << "[" << (str?str:"mysql") << "]errno:" << m_errno << ":" << mysql_error(m_pConnect);
	m_error = s.str();
}

}
